1 00:00:00,140 --> 00:00:02,330 Before we get started working on our final project. 2 00:00:02,330 --> 00:00:06,650 I think it's very important for us to completely understand how replication works and when you should 3 00:00:06,650 --> 00:00:09,500 use the weight for child function in your local scripts. 4 00:00:09,500 --> 00:00:12,380 You should already have a pretty decent understanding of replication. 5 00:00:12,380 --> 00:00:16,520 Basically, when a player joins a game, they download their own copy of the game like all the part 6 00:00:16,520 --> 00:00:21,200 scripts and other players, and the server tells the players to adjust the properties of those instances 7 00:00:21,200 --> 00:00:21,920 when needed. 8 00:00:21,920 --> 00:00:26,720 This way, a player's copy of the game stays separate from the server's copy, and any changes the player 9 00:00:26,720 --> 00:00:30,050 makes on their copy of the game does not affect the server's copy. 10 00:00:30,560 --> 00:00:35,000 As an example, we're going to see replication in action here with this client and server setup. 11 00:00:35,000 --> 00:00:38,450 Here I have in studio now to see incoming and outgoing data. 12 00:00:38,450 --> 00:00:44,150 We can go into the view tab and go down to the stats section and enable the network UI. 13 00:00:44,150 --> 00:00:46,550 And we can do this for both the client and the server. 14 00:00:48,660 --> 00:00:53,190 So now here on the server, I can go ahead and see all the data that is being sent out. 15 00:00:53,190 --> 00:00:56,820 And here on the client, I could go ahead and see all the data that I am receiving. 16 00:00:56,820 --> 00:01:04,260 So currently we're at 0.15kB per second and outgoing from the server again is 0.015. 17 00:01:05,250 --> 00:01:09,900 Now, if I were to create a new part on the server here and let me just go and place one like right 18 00:01:09,900 --> 00:01:10,410 here. 19 00:01:11,390 --> 00:01:16,880 We did send out a little bit more data to tell the player to create a new part on their copy of the 20 00:01:16,880 --> 00:01:17,360 game. 21 00:01:17,360 --> 00:01:20,600 So here in my copy of the game, there's this new part here. 22 00:01:21,490 --> 00:01:26,350 And then when the server starts to move this part, it's going to tell this player to start moving it 23 00:01:26,350 --> 00:01:28,180 on their copy of the game as well. 24 00:01:28,210 --> 00:01:33,250 So as I start to move the part, you can see that the outgoing data is increasing. 25 00:01:33,460 --> 00:01:38,770 And then if you look at the client as well, our overall incoming data has also been increased. 26 00:01:39,160 --> 00:01:43,810 Now because this part is unanchored, my player currently has network ownership over it. 27 00:01:43,810 --> 00:01:47,650 Or basically my computer is calculating the physics for this part. 28 00:01:47,650 --> 00:01:52,270 And because I have network ownership, I can move this part and it will replicate to the server. 29 00:01:52,270 --> 00:01:58,600 So if I start moving the part, as you can see now, I'm sending data out from my computer and the server 30 00:01:58,600 --> 00:02:00,580 is receiving some data as well. 31 00:02:01,430 --> 00:02:06,620 So again, as I continue to move it, you can see that the data in the out physics section has increased 32 00:02:06,620 --> 00:02:10,070 and the server is getting more data coming into it. 33 00:02:10,520 --> 00:02:14,030 Now that means if I want to go and anchor the part on the server. 34 00:02:15,540 --> 00:02:19,140 So let me go to the model tab parts and then let me anchor this part. 35 00:02:19,260 --> 00:02:21,630 That means I have disabled physics on the part. 36 00:02:21,630 --> 00:02:25,470 And now my player here doesn't have a network ownership over this part anymore. 37 00:02:25,470 --> 00:02:29,880 So if I start to move it, as you can see, I'm only moving it on my copy of the game. 38 00:02:29,880 --> 00:02:34,890 I'm not sending out any data for physics, and the server doesn't see that I'm moving it at all. 39 00:02:34,890 --> 00:02:39,390 However, if the server starts moving, it's going to tell my player to update it to this new position 40 00:02:39,390 --> 00:02:40,350 that the server moved it to. 41 00:02:40,380 --> 00:02:44,370 So if I move it like over here, there you can see it replicated to my copy of the game. 42 00:02:45,160 --> 00:02:49,870 And again, because my copy is separate from the server's, anything I do here does not replicate to 43 00:02:49,870 --> 00:02:53,110 the server, nor does it replicate to other players in the game. 44 00:02:53,110 --> 00:02:55,780 It's only affecting my copy of the game. 45 00:02:56,220 --> 00:03:01,950 So the only exception of things that are replicated from my game to the server and the server broadcasts, 46 00:03:01,950 --> 00:03:07,560 that replication to other players would be the movement of my character and any other parts that I have 47 00:03:07,560 --> 00:03:09,240 network ownership of. 48 00:03:09,270 --> 00:03:14,670 Other than that, anything else I change in my game, such as changing the color of these houses, making 49 00:03:14,670 --> 00:03:18,510 one fly up in the sky, or anything of that kind of nature. 50 00:03:18,510 --> 00:03:21,120 It's not going to be replicated to the server or other players. 51 00:03:21,120 --> 00:03:23,040 It's only going to happen on my game. 52 00:03:23,640 --> 00:03:28,170 Okay, so now that we have a pretty good understanding of replication, let's go ahead and take a dive 53 00:03:28,170 --> 00:03:33,270 into specifically when you should use wait for child and when you should not use wait for child. 54 00:03:33,330 --> 00:03:38,370 So as you already know, the wait for child function allows a local script to yield until an instance 55 00:03:38,370 --> 00:03:40,560 has been replicated to their copy of the game. 56 00:03:40,560 --> 00:03:43,140 This prevents us from causing errors in our scripts. 57 00:03:43,140 --> 00:03:47,880 When we try to directly index or access an instance that hasn't been replicated yet. 58 00:03:48,420 --> 00:03:52,650 However, there is a lot of confusion surrounding wait for child and when you're supposed to use it. 59 00:03:53,310 --> 00:03:57,960 Now, when a player joins a game, there's going to be an event that gets fired once a snapshot of the 60 00:03:57,960 --> 00:04:01,320 game has been fully replicated to our side of the game. 61 00:04:01,320 --> 00:04:06,600 So this is inside of game, which is the data model for our whole game. 62 00:04:06,600 --> 00:04:10,920 And this event is called loaded and it fires on the client when the game finishes loading for the first 63 00:04:10,920 --> 00:04:11,370 time. 64 00:04:11,370 --> 00:04:13,230 What does it mean when it finishes loading. 65 00:04:13,230 --> 00:04:17,280 Well, that means we receive a snapshot of the entire game. 66 00:04:17,280 --> 00:04:22,200 So all the contents of the workspace replicated storage things and like the sound service and all of 67 00:04:22,200 --> 00:04:27,210 these other sections, we get the snapshot of the game and we replicate it. 68 00:04:27,210 --> 00:04:31,680 And then once those items have been fully replicated, then this loaded event fires. 69 00:04:31,680 --> 00:04:37,110 Now any local scripts that you have within these starter sections like the starter pack, starter player, 70 00:04:37,110 --> 00:04:43,530 starter guy, things of that nature, they are not going to execute until our game has been loaded. 71 00:04:43,980 --> 00:04:48,570 So any instances that you have saved inside of studio that are a part of your game will be inside of 72 00:04:48,570 --> 00:04:53,430 that snapshot, and they'll be immediately accessible to your local scripts that are inside of your 73 00:04:53,430 --> 00:04:54,990 different starter containers. 74 00:04:55,410 --> 00:05:02,790 Now, these instances are known as static, and you do not need to worry about waiting for them to replicate. 75 00:05:02,790 --> 00:05:06,810 And because you don't need to worry about them having to replicate, that means you do not need to use 76 00:05:06,810 --> 00:05:09,180 wait for child on static instances. 77 00:05:09,180 --> 00:05:14,970 However, there are other instances that will be generated during the runtime of our game, like a player's 78 00:05:14,970 --> 00:05:21,330 character, maybe instances created by server scripts, instances copied to the workspace from like 79 00:05:21,330 --> 00:05:22,890 server storage and so on. 80 00:05:22,890 --> 00:05:26,400 And all of those are known as dynamic instances. 81 00:05:28,290 --> 00:05:33,120 So again, anything created during the runtime of your game is going to be a dynamic instance. 82 00:05:33,570 --> 00:05:37,710 These instances are basically placed in a queue to be replicated to you. 83 00:05:37,920 --> 00:05:43,110 You can't rely on them existing when your scripts run, so you have to use wait for trial on dynamic 84 00:05:43,110 --> 00:05:43,920 instances. 85 00:05:43,920 --> 00:05:49,980 So for example, if I had a guy within our starter guy, let's say I had a screen guy in here with some 86 00:05:49,980 --> 00:05:52,770 different stuff in it, like frames and whatnot. 87 00:05:52,770 --> 00:05:58,200 If I had a script inside of starter player scripts that wanted to access this guy when it is placed 88 00:05:58,200 --> 00:06:04,860 inside of our player guy folder, then because it's cloned, the only thing I would need to wait for 89 00:06:04,860 --> 00:06:06,600 is the screen guy itself. 90 00:06:06,600 --> 00:06:12,300 The starter guy service has already been loaded by the time the script will run, and that means all 91 00:06:12,300 --> 00:06:17,220 I need to wait for is when the screen guy gets cloned into our player guy folder, and I don't need 92 00:06:17,220 --> 00:06:19,290 to wait for any of the other descendants. 93 00:06:19,290 --> 00:06:25,380 This is because cloning is known as a synchronous operation, or basically all of the descendants from 94 00:06:25,380 --> 00:06:30,390 the root, which would be this guy are going to be immediately available once the root has been cloned 95 00:06:30,390 --> 00:06:32,700 and replicated to our copy of the game. 96 00:06:32,880 --> 00:06:40,530 So if I ever wanted to access my local player and get our player guy folder, I would have to wait for 97 00:06:40,530 --> 00:06:42,360 this particular screen guy. 98 00:06:42,360 --> 00:06:47,430 And then once I've waited for the screen guy, I no longer need to wait for any of the other descendants 99 00:06:47,430 --> 00:06:52,890 of the screen guy so I can access the frame freely without having to worry about it not existing. 100 00:06:53,370 --> 00:06:59,880 I also don't need to wait for the player guy folder either, because it's guaranteed to be non-nil when 101 00:06:59,880 --> 00:07:01,590 you index the local player. 102 00:07:01,590 --> 00:07:07,290 Now, if I had a local script within the screen guy, well, that makes it even easier because I can 103 00:07:07,290 --> 00:07:12,150 just reference the guy itself using script dot parent, and because again, the script is only going 104 00:07:12,150 --> 00:07:16,530 to run when it's been loaded and this guy has been copied to our player guy. 105 00:07:16,530 --> 00:07:21,420 I don't need to wait for any of the descendants either, so I can access script Dot parent and get things 106 00:07:21,420 --> 00:07:22,170 like the frame. 107 00:07:22,170 --> 00:07:23,700 I don't need to wait for any of it. 108 00:07:23,700 --> 00:07:27,300 It's already been replicated and they are static instances. 109 00:07:27,720 --> 00:07:29,880 All right, so let me go ahead and summarize this for you. 110 00:07:29,880 --> 00:07:34,890 Any local scripts that exist within the starter containers, like starter player scripts or the starter 111 00:07:34,890 --> 00:07:39,330 guy, they do not need to use wait for child on static instances. 112 00:07:39,330 --> 00:07:45,210 And a static instance is all the instances that exist within the snapshot of the game that is downloaded 113 00:07:45,210 --> 00:07:46,950 by a player when they join the game. 114 00:07:46,950 --> 00:07:53,070 However, any local scripts that are going to be inside of something like replicated first are going 115 00:07:53,070 --> 00:07:59,070 to have to use wait for child, because if they try to access any instances outside of replicated first, 116 00:07:59,070 --> 00:08:02,910 there's no guarantee that those instances have been replicated yet. 117 00:08:03,880 --> 00:08:08,980 You're also going to have to use weight for child on dynamic instances, or any instances that are added 118 00:08:08,980 --> 00:08:10,810 during the runtime of the game. 119 00:08:11,080 --> 00:08:15,340 If a player reset and a new character was added to that player, well, you're going to have to use 120 00:08:15,340 --> 00:08:17,560 weight for child because that's a dynamic instance. 121 00:08:17,560 --> 00:08:20,440 Did the server just add some new instances into the game? 122 00:08:20,440 --> 00:08:23,920 Well, you got to wait for those as well because that's a dynamic instance. 123 00:08:24,130 --> 00:08:27,370 So let's go ahead and take a look at this diagram about replication. 124 00:08:27,370 --> 00:08:31,180 So as you can see right here this is when our player connects to the game. 125 00:08:31,180 --> 00:08:33,190 And when our player connects into the game. 126 00:08:33,190 --> 00:08:37,240 Then we get a snapshot of everything that's going to be inside of replicated first. 127 00:08:37,240 --> 00:08:39,190 And that begins to load. 128 00:08:39,190 --> 00:08:45,130 And then once replicated first is finished loading any scripts that are inside of replicated first begin 129 00:08:45,130 --> 00:08:45,850 to run. 130 00:08:45,850 --> 00:08:51,520 That means if you had a script inside of replicated first, and you had some other stuff in here, like 131 00:08:51,520 --> 00:08:56,770 a part when the script runs, I don't need to wait for this part that's already inside of replicated. 132 00:08:56,770 --> 00:09:02,260 First, it's a static instance, so I could just do game Dot replicated first and immediately access 133 00:09:02,260 --> 00:09:04,450 this part without having to use wait for child. 134 00:09:04,450 --> 00:09:11,650 However, because the script is running before our game loads anything outside of replicated. 135 00:09:11,650 --> 00:09:13,990 First you must use wait for child on. 136 00:09:14,410 --> 00:09:19,300 So if I wanted to access something in the workspace from this local script and replicated first, for 137 00:09:19,300 --> 00:09:22,990 some reason I will have to use wait for child. 138 00:09:23,170 --> 00:09:29,650 I cannot directly index anything in the workspace because there's no guarantee that it will exist when 139 00:09:29,650 --> 00:09:30,610 the script runs. 140 00:09:30,610 --> 00:09:36,160 So as proof, what I'm going to do is I'm actually going to print the number of descendants that are 141 00:09:36,160 --> 00:09:36,910 in the workspace. 142 00:09:36,910 --> 00:09:39,700 So we can just do workspace, get descendants. 143 00:09:40,330 --> 00:09:46,390 And then I'm going to do the exact same thing here within our starter player script, I'm going to print 144 00:09:46,720 --> 00:09:49,690 the number of descendants in the workspace. 145 00:09:51,530 --> 00:09:56,750 So basically this script right here should print like one, because the only thing that will be loaded 146 00:09:56,750 --> 00:09:59,030 is likely going to be the terrain. 147 00:10:00,450 --> 00:10:06,810 And then this one should print all of the stuff that exists within the workspace, because the script 148 00:10:06,810 --> 00:10:09,330 will only run once the game has been loaded. 149 00:10:09,720 --> 00:10:12,450 So if we go ahead and play test the game. 150 00:10:13,680 --> 00:10:14,610 We're going to go ahead. 151 00:10:14,640 --> 00:10:14,850 See? 152 00:10:14,880 --> 00:10:24,330 Look it printed one and then our other script printed 161,606 instances within the workspace. 153 00:10:24,330 --> 00:10:29,400 So as you can see that script that's in replicated first, none of those assets, like all of these 154 00:10:29,400 --> 00:10:32,220 houses that I made, have been replicated to the client yet. 155 00:10:32,220 --> 00:10:37,830 So you have to use wait for child when you access anything outside of replicated first in a local script. 156 00:10:37,830 --> 00:10:43,500 However, because my other script was inside of a starter player container, it wasn't going to run 157 00:10:43,500 --> 00:10:47,070 until the first snapshot that was given to me has been replicated. 158 00:10:47,070 --> 00:10:53,280 So that means inside of that script in my starter player scripts, I can go ahead and freely access 159 00:10:53,280 --> 00:10:57,000 any of these houses without worrying about them not being replicated. 160 00:10:57,450 --> 00:10:59,880 Now, I'm also going to show you something a little bit interesting. 161 00:10:59,880 --> 00:11:05,670 I'm going to wait three seconds and then after those three seconds, I'm going to print the workspace, 162 00:11:05,670 --> 00:11:08,910 get descendants again, and then inside a replicated. 163 00:11:08,910 --> 00:11:13,440 First I'm going to do the same thing, but I'm only going to wait something like 0.1 seconds and we're 164 00:11:13,440 --> 00:11:16,230 going to print the workspace, get descendants again. 165 00:11:16,590 --> 00:11:22,830 So we should be able to see how many instances had loaded inside of our workspace after 0.1 seconds 166 00:11:22,830 --> 00:11:23,910 has elapsed. 167 00:11:24,270 --> 00:11:29,610 So if we hit play, our game is loading and we should see one get printed. 168 00:11:31,210 --> 00:11:31,570 There we go. 169 00:11:31,570 --> 00:11:32,560 We got one. 170 00:11:33,490 --> 00:11:38,800 Then we got 161,606 and actually replicated first printed that as well. 171 00:11:38,800 --> 00:11:42,400 So maybe 18.1 seconds is actually a little too short. 172 00:11:42,400 --> 00:11:47,230 So what I could do is let me wait even a shorter period of time. 173 00:11:48,130 --> 00:11:54,010 Because the server has been run on my computer, the latency between the server and the client is basically 174 00:11:54,010 --> 00:11:56,200 zero, so everything loads super fast. 175 00:11:56,200 --> 00:11:57,250 But there we go. 176 00:11:57,310 --> 00:12:05,680 You see, first it printed one and then we waited 0.001 seconds and then it printed 21,049 objects. 177 00:12:05,680 --> 00:12:08,200 So not everything in the workspace had been loaded yet. 178 00:12:08,200 --> 00:12:14,260 Then the local script that was inside of starter player printed 161,606. 179 00:12:14,260 --> 00:12:19,450 And then you're going to see, wait, why did the number increase if everything had already been loaded 180 00:12:19,450 --> 00:12:22,150 in our game, why did more things load? 181 00:12:22,670 --> 00:12:28,700 Well, all those additional instances were actually part of our player model. 182 00:12:28,700 --> 00:12:33,770 So as you know, our player model doesn't exist in that snapshot that gets replicated to our computer. 183 00:12:33,800 --> 00:12:36,770 Our player's character is a dynamic instance. 184 00:12:36,770 --> 00:12:42,680 So that means we had to wait for it to get replicated to our copy of the game and spawned in. 185 00:12:42,680 --> 00:12:47,150 And as you can see, all of these different instances in here had to be replicated. 186 00:12:47,540 --> 00:12:52,700 So our player's character would be known as a dynamic instance, which is why it didn't print originally 187 00:12:52,700 --> 00:12:54,110 when that local script ran. 188 00:12:54,880 --> 00:12:57,310 So what do we learn from all of this? 189 00:12:57,340 --> 00:13:03,940 Well, any local scripts that are inside of replicated first can safely access instances inside of replicated 190 00:13:03,940 --> 00:13:04,450 first. 191 00:13:04,450 --> 00:13:10,090 But those scripts must use wait for child on instances outside of replicated first. 192 00:13:10,090 --> 00:13:16,000 So if my script wanted to access any instance like in the workspace lighting sound service, it must 193 00:13:16,000 --> 00:13:20,800 use wait for child any local script that are inside of the starter containers like starter, player, 194 00:13:20,800 --> 00:13:23,710 scripts, starter, GUI and so on. 195 00:13:23,710 --> 00:13:28,840 They will execute after the game has been loaded so they are able to freely access static instances 196 00:13:28,840 --> 00:13:34,030 in the game services like the workspace, replicated storage and other services. 197 00:13:34,030 --> 00:13:40,330 However, they must use wait for child on dynamic instances like the player's character guy is copied 198 00:13:40,330 --> 00:13:45,520 to the player's player guy folder, instances created by a server, scripts during runtime, and stuff 199 00:13:45,520 --> 00:13:46,210 like that. 200 00:13:46,420 --> 00:13:50,740 Hopefully this lecture helped to clear up any confusion on replication and wait for child. 201 00:13:50,740 --> 00:13:55,420 And we're going to begin to apply this knowledge about replication in our final project. 202 00:13:55,420 --> 00:13:56,590 Thanks for listening.